package com.project.frba.bifront.client.view;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.Window;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.form.Label;
import com.gwtext.client.widgets.layout.FitLayout;
import com.gwtext.client.widgets.layout.HorizontalLayout;
import com.gwtext.client.widgets.layout.VerticalLayout;
import com.project.frba.bifront.client.model.Filter;

public class FilterSelector extends Composite{
	
	private Window mainWindow = new Window();
	private Map<String, List<String>> filtersMap = new HashMap<String, List<String>>();
	private ListBox properties = new ListBox();
	private ListBox availableFilters = new ListBox();
	private ListBox	appliedFilters = new ListBox();
	private Button buttonAddFilter = new Button("-->");
	private Button buttonRemoveFilter = new Button("<--");
	private Button buttonSave = new Button("Guardar");
	private CubePanel cubePanel;
	
	public FilterSelector(){
		
	}
	
	public FilterSelector(Collection<String> propertyNames, List<Filter> savedFilters , CubePanel  parent){
		cubePanel = parent;

		Panel mainPanel = new Panel();
		mainPanel.setLayout(new VerticalLayout(3));
		Label lbAvailableValues = new Label("Filtrar");
		Label lbAppliedValues = new Label("Filtros aplicados");
		Label lbProperties = new Label("Selecciona la propiedad a filtrar");
		
		this.properties.addItem("", "");
		for (String propertyName : propertyNames) {
			this.properties.addItem(parent.getLabelForProperty(propertyName), propertyName);
			filtersMap.put(propertyName, new ArrayList<String>());
		}
		
		if(savedFilters.size() > 0){
			for (Filter savedFilter: savedFilters) {
				filtersMap.put(savedFilter.getPropertyName(), savedFilter.getFilterValues());
			}
		}
		
		appliedFilters.setVisibleItemCount(8);
		appliedFilters.setWidth("250px");
		availableFilters.setVisibleItemCount(8);
		availableFilters.setWidth("250px");
		
		
		//mainPanel
		Panel topPanel = new Panel();
		topPanel.setLayout(new VerticalLayout(3));
		topPanel.setPaddings(2);
		topPanel.add(lbProperties);
		topPanel.add(properties);
		
		mainPanel.add(topPanel);
		
		Panel bottomPanel = new Panel();
		bottomPanel.setPaddings(2);
		bottomPanel.setLayout(new HorizontalLayout(3));
		
		Panel availablePanel = new Panel();
		availablePanel.setLayout(new VerticalLayout(2));
		availablePanel.add(lbAvailableValues);
		availablePanel.add(availableFilters);
		bottomPanel.add(availablePanel);
		
		Panel buttonPanel = new Panel();
		buttonPanel.setLayout(new VerticalLayout(2));
		buttonPanel.add(buttonAddFilter);
		buttonPanel.add(buttonRemoveFilter);
		bottomPanel.add(buttonPanel);
		
		Panel appliedPanel = new Panel();
		appliedPanel.setLayout(new VerticalLayout(2));
		appliedPanel.add(lbAppliedValues);
		appliedPanel.add(appliedFilters);
		bottomPanel.add(appliedPanel);
		
		mainPanel.add(bottomPanel);
		
		loadActions();
		
		
		//window
		mainWindow.setButtons(new Button[]{buttonSave});
		mainWindow.setLayout(new FitLayout());
		mainWindow.setTitle("Configurar filtros");
		mainWindow.setPaddings(5);
		mainWindow.setWidth(580);
		mainWindow.setHeight(340);
		mainWindow.setResizable(false);
		mainWindow.setClosable(true);
		mainWindow.add(mainPanel);
		initWidget(mainWindow);
		
	}	
	
	private void loadValues(final String propertyName) {
		AsyncCallback<List<String>> cbValues = new AsyncCallback<List<String>>(){

			public void onFailure(Throwable caught) {
				com.google.gwt.user.client.Window.alert("RPC failed.");
			}

			public void onSuccess(List<String> result) {
				List<String> filtersList = filtersMap.get(propertyName);
				for (String propertyValue : result) {
					if(filtersList.contains(propertyValue)){
						appliedFilters.addItem(propertyValue, propertyValue);
					} else {
						availableFilters.addItem(propertyValue, propertyValue);	
					}
				}
			}
			
		};
		
		cubePanel.getValuesForProperty(propertyName, cbValues);
	}

	private void loadActions() {
		properties.addChangeListener(new ChangeListener(){
			public void onChange(Widget sender) {
				ListBox lbSender = (ListBox)sender;
				String propertyName = lbSender.getValue(lbSender.getSelectedIndex());
				if(!"".equals(propertyName)){
					appliedFilters.clear();
					availableFilters.clear();
					loadValues(propertyName);					
				}
			}
		});
		
		buttonSave.addListener(new ButtonListenerAdapter(){
			public void onClick(Button button, EventObject e) {
				cubePanel.setFilters(getSelectedFilters());
				mainWindow.close();
			}
		});
		
		
		buttonAddFilter.addListener(new ButtonListenerAdapter(){
			public void onClick(Button button, EventObject e) {
				String propertyName = properties.getValue(properties.getSelectedIndex());
				if(!"".equals(propertyName)){
					Integer index = availableFilters.getSelectedIndex();
					String selectedValue = availableFilters.getValue(index);
					appliedFilters.addItem(selectedValue, selectedValue);
					availableFilters.removeItem(index);
					filtersMap.get(propertyName).add(selectedValue);
				}
			}
		});
		
		buttonRemoveFilter.addListener(new ButtonListenerAdapter(){
			public void onClick(Button button, EventObject e) {
				String propertyName = properties.getValue(properties.getSelectedIndex());
				if (!"".equals(propertyName)) {
					Integer index = appliedFilters.getSelectedIndex();
					String selectedValue = appliedFilters.getValue(index);
					availableFilters.addItem(selectedValue, selectedValue);
					appliedFilters.removeItem(index);
					
					filtersMap.get(propertyName).remove(selectedValue);
				}
				
			}
		});
		
	}

	public List<Filter> getSelectedFilters(){
		List<Filter> filters = new ArrayList<Filter>();
		for (String propertyName : this.filtersMap.keySet()) {
			if(filtersMap.get(propertyName).size() > 0){
				Filter filter = new Filter(propertyName);
				filter.addFilterValues(this.filtersMap.get(propertyName));
				filters.add(filter);				
			}
		}
		
		return filters;
	}
	
	
	public void show(){
		mainWindow.show();
	}
	
	
}
